package com.ant.backstage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ant.backstage.dao.PermissionMapper;
import com.ant.backstage.dao.RoleMapper;
import com.ant.backstage.dao.RolepermissionMapper;
import com.ant.backstage.dao.UserroleMapper;
import com.ant.backstage.facade.ApiReturn;
import com.ant.backstage.facade.code.ApiReturnCode;
import com.ant.backstage.facade.dto.UserDTO;
import com.ant.backstage.facade.enums.PermissionEnum;
import com.ant.backstage.facade.exception.BackstageBusinessException;
import com.ant.backstage.facade.model.*;
import com.ant.backstage.facade.request.power.AllocationRoleRequest;
import com.ant.backstage.facade.request.power.RoleAddRequest;
import com.ant.backstage.facade.response.vo.PermissionVo;
import com.ant.backstage.facade.response.vo.RoleVo;
import com.ant.backstage.service.RoleService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import ma.glasnost.orika.MapperFacade;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service("roleService")
public class RoleServiceImpl  implements RoleService {

    private static Logger logger = LogManager.getLogger(RoleServiceImpl.class);

    @Resource
    RoleMapper roleMapper;
    @Resource
    MapperFacade mapperFacade;
    @Resource
    RolepermissionMapper rolepermissionMapper;
    @Resource
    UserroleMapper userroleMapper;
    @Resource
    PermissionMapper permissionMapper;

    @Override
    public PageInfo selectRoles(Role role, int pageNum, int pageSize, String uid) {
        //根据条件查符合条件的IDs
        List<Integer> roleIds = roleMapper.selectRolesByTerm(role);
        if (Optional.ofNullable(uid).isPresent()) {
            List<Userrole> userroles = userroleMapper.selectRoleByUid(uid);
            List<Integer> collect = userroles.stream().map(Userrole::getRoleId).collect(Collectors.toList());
            roleIds.retainAll(collect);
        }
        PageInfo<Object> pageInfo = null;
        List<Role> resultList = null;
        if (!roleIds.isEmpty()) {
            //使用pageHelper实现分页查询  注意设置完 pageHelper 以后需要接着查询
            PageHelper.startPage(pageNum,pageSize);
            resultList = roleMapper.selectRoleByids(roleIds);
            pageInfo = new PageInfo(resultList);
        }else {
            logger.info("分页查询,没有符合条件的用户 roleIds={},resultList={}",
                    JSONObject.toJSONString(roleIds),JSONObject.toJSONString(resultList));
            return pageInfo;
        }
        List<RoleVo> roleVos = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        resultList.forEach(r->{
            RoleVo vo = mapperFacade.map(r, RoleVo.class);
            List<Rolepermission> rolepermissions = rolepermissionMapper.selectByRoleId(r.getId());
            List<Permission> permissions = permissionMapper.selectByids(rolepermissions.stream().map(Rolepermission::getPermissionId).collect(Collectors.toList()));
            List<PermissionVo> permissionVos = new ArrayList<>();
            permissions.stream().forEach(p->{
                PermissionVo pvo = mapperFacade.map(p, PermissionVo.class);
                pvo.setCreateTime(sdf.format(p.getCreateTime()));
                pvo.setLastUpdateTime(sdf.format(p.getLastUpdateTime()));
                //权限类型
                PermissionEnum byCode = PermissionEnum.getByCode(String.valueOf(p.getMenu()));
                if(byCode == null){
                    logger.error("权限类型，枚举值异常 permission={}" ,p);
                    throw new BackstageBusinessException(ApiReturnCode.HTTP_ERROR.getMessage(),ApiReturnCode.HTTP_ERROR.getCode());
                }
                switch (byCode){
                    case FIRST_LEVEL_MENU:
                        pvo.setPermissionType(byCode.getDesc());
                        break;
                    case TWO_LEVEL_MENU:
                        pvo.setPermissionType(byCode.getDesc());
                        break;
                }
                permissionVos.add(pvo);
            });
            vo.setCreateTime(sdf.format(r.getCreateTime()));
            vo.setLastUpdateTime(sdf.format(r.getLastUpdateTime()));
            vo.setPerList(permissionVos);
            roleVos.add(vo);
        });
        pageInfo.setList(Collections.singletonList(roleVos));
        return pageInfo;
    }

    @Override
    public List<Role> selectAllRole() {
        return roleMapper.selectAll();
    }
    @Override
    public Role selectRolesById(int id) {
        return roleMapper.selectByPrimaryKey(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    //TODO 事务
    public ApiReturn addRole(RoleAddRequest roleAddRequest, UserDTO userPo) {
        ApiReturn apiReturn = new ApiReturn();
        Role role = mapperFacade.map(roleAddRequest, Role.class);
        role.setCreateTime(new Date());
        role.setLastUpdateTime(new Date());
        role.setCreator(userPo.getUname());
        role.setEditor(userPo.getUname());
        int count = roleMapper.selectByName(role.getRolename());
        if (count >= 1) {
            logger.error("新增角色，角色名不能重复 roleAddRequest={}", JSONObject.toJSONString(roleAddRequest));
            apiReturn.setMsg(ApiReturnCode.ROLE_NAME_REPEAT.getMessage());
            apiReturn.setCode(ApiReturnCode.ROLE_NAME_REPEAT.getCode());
            apiReturn.setData(roleAddRequest);
            return apiReturn;
        }
        int id = roleMapper.insert(role);
        List<String> perIds = roleAddRequest.getPerIds();
        perIds.forEach(r->{
            Rolepermission rolepermission = new Rolepermission();
            rolepermission.setPermissionId(Integer.valueOf(r));
            rolepermission.setRoleId(role.getId());
            rolepermissionMapper.insert(rolepermission);
        });
        apiReturn.setApiReturnCode(ApiReturnCode.SUCCESSFUL);
        return apiReturn;
    }

    @Override
    public ApiReturn updateRolesStatus(String statusId, String roleId, ApiReturn apiReturn, UserDTO userPo) {
        //   修改的角色当前账户是否拥有该角色
        Userrole userrole = userroleMapper.selectRoleByUidAndRoleId(roleId, userPo.getUid());
        if (!Optional.ofNullable(userrole).isPresent()) {
            logger.error("修改角色状态，当前用户不具备修改的角色，修改失败 statusId={}," +
                    "roleId={},userPo={}", statusId,roleId,JSONObject.toJSONString(userPo));
            apiReturn.setCode(ApiReturnCode.ROLE_UPDATE_STATUS_ERROR.getCode());
            apiReturn.setMsg(ApiReturnCode.ROLE_UPDATE_STATUS_ERROR.getMessage());
            return apiReturn;
        }
        roleMapper.updateByPrimaryKey(Integer.valueOf(roleId),Integer.valueOf(statusId));
        apiReturn.setApiReturnCode(ApiReturnCode.SUCCESSFUL);
        return apiReturn;
    }

    @Override
    public ApiReturn removeRolePermission(String roleId, String perId, UserDTO userPo) {
        //   修改的角色当前账户是否拥有该角色
        Userrole userrole = userroleMapper.selectRoleByUidAndRoleId(roleId, userPo.getUid());
        ApiReturn apiReturn = new ApiReturn();
        if (!Optional.ofNullable(userrole).isPresent()) {
            logger.error("移除角色下的权限,当前用户不具备修改的角色，修改失败 roleId={}," +
                    "perId={},userPo={}", roleId,perId,JSONObject.toJSONString(userPo));
            apiReturn.setCode(ApiReturnCode.ROLE_UPDATE_STATUS_ERROR.getCode());
            apiReturn.setMsg(ApiReturnCode.ROLE_UPDATE_STATUS_ERROR.getMessage());
            return apiReturn;
        }
        rolepermissionMapper.delByRoleAndPreId(roleId,perId);
        apiReturn.setApiReturnCode(ApiReturnCode.SUCCESSFUL);
        return apiReturn;
    }

    @Override
    public ApiReturn allocationRolePermission(AllocationRoleRequest allocationRoleRequest, UserDTO userPo) {
        ApiReturn apiReturn = new ApiReturn();
        //校验当前用户是否有该角色
        Userrole userroles = userroleMapper.selectRoleByUidAndRoleId(String.valueOf(allocationRoleRequest.getRoleId()),userPo.getUid());
        if (!Optional.ofNullable(userroles).isPresent()) {
            apiReturn.setCode(ApiReturnCode.ROLE_UPDATE_STATUS_ERROR.getCode());
            apiReturn.setMsg(ApiReturnCode.ROLE_UPDATE_STATUS_ERROR.getMessage());
            return apiReturn;
        }
        // 1. 角色ID 所拥有的权限
        List<Rolepermission> rolepermissions = rolepermissionMapper.selectByRoleId(allocationRoleRequest.getRoleId());
        //2. 移除所有的权限
        rolepermissions.forEach(r->{
            rolepermissionMapper.delByRoleAndPreId(String.valueOf(r.getRoleId()),String.valueOf(r.getPermissionId()));
        });
        //合并权限id
        List<Integer> list = allocationRoleRequest.getOldPerIdList();
        list.addAll(allocationRoleRequest.getNewPerIdList());
        list.forEach(perId->{
            Rolepermission rolepermission = new Rolepermission();
            rolepermission.setRoleId(allocationRoleRequest.getRoleId());
            rolepermission.setPermissionId(perId);
            rolepermissionMapper.insert(rolepermission);
        });
        apiReturn.setApiReturnCode(ApiReturnCode.SUCCESSFUL);
        return apiReturn;
    }

    @Override
    public List<Role> selectRolesByUid(String uid) {
        List<Userrole> userroles = userroleMapper.selectRoleByUid(uid);
        List<Integer> collect = userroles.stream().map(Userrole::getRoleId).collect(Collectors.toList());
        if (collect.isEmpty()) {
            return null;
        }
        List<Role> roles = roleMapper.selectRoleByids(collect);
        return roles;
    }
}
